﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Common;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Model.Wcs;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class TransferBinOrderService : BaseService, ITransferBinOrderService
    {
        private readonly ITransferBinOrderDetailRepository _transferBinOrderDetailRepository;
        private readonly IReceivingOrderDetailRepository _receivingOrderDetailRepository;
        private readonly ITransferBinOrderRepository _transferBinOrderRepository;
        private readonly IShippingLockCellRepository _lockCellRepository;
        private readonly IInventoryLogRepository _inventoryLogRepository;
        private readonly IPutawayOrderRepository _pingOrderRepository;
        private readonly IInventoryRepository _inventoryRepository;
        private readonly IInstructRepository _instructRepository;
        private readonly IPalletRepository _alletRepository;
        private readonly ICellRepository _cellRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly WcsHttpClient wcsHttp;
        private readonly IAreaRepository areaRepository;
        private readonly IWarehouseRepository warehouseRepository;
        private readonly IRoutewayRepository routewayRepository;
        private readonly IShelfRepository shelfRepository;

        public TransferBinOrderService(IMapper mapper, ITransferBinOrderDetailRepository transferBinOrderDetailRepository, ITransferBinOrderRepository transferBinOrderRepository, IUnitOfWork unitOfWork, IInventoryRepository inventoryRepository, ICellRepository cellRepository, IReceivingOrderDetailRepository receivingOrderDetailRepository, IInstructRepository instructRepository, IPutawayOrderRepository pingOrderRepository, IPalletRepository alletRepository, IInventoryLogRepository inventoryLogRepository, IShippingLockCellRepository _lockCellRepository, WcsHttpClient wcsHttp, IAreaRepository areaRepository, IWarehouseRepository warehouseRepository, IRoutewayRepository routewayRepository, IShelfRepository shelfRepository) : base(mapper)
        {
            this._lockCellRepository = _lockCellRepository;
            this.wcsHttp = wcsHttp;
            this.areaRepository = areaRepository;
            this.warehouseRepository = warehouseRepository;
            this.routewayRepository = routewayRepository;
            this.shelfRepository = shelfRepository;
            _transferBinOrderDetailRepository = transferBinOrderDetailRepository;
            _receivingOrderDetailRepository = receivingOrderDetailRepository;
            _transferBinOrderRepository = transferBinOrderRepository;
            _inventoryLogRepository = inventoryLogRepository;
            _inventoryRepository = inventoryRepository;
            _pingOrderRepository = pingOrderRepository;
            _instructRepository = instructRepository;
            _alletRepository = alletRepository;
            _cellRepository = cellRepository;
            _unitOfWork = unitOfWork;
        }
        #region PC
        public bool AddTransferBinOrder(TransferBinOrder m, out string message)
        {
            message = "";
            m.Status = 0;
            var ilist = _inventoryRepository.GetEntityAlls().ToList();
            var clist = _cellRepository.GetEntityAlls().ToList();
            _unitOfWork.BeginTransaction();
            foreach (var item in m.OrderDetailList)
            {
                var ilists = ilist.Where(x => x.LocationId == item.FromLocationId && x.Status == 1);
                if (!ilists.Any())
                {
                    message = "找不到库存信息！";
                    return false;
                }
                foreach (var iobj in ilists)
                {
                    iobj.IsLock = true;
                    _inventoryRepository.UpdEntity(iobj);
                }
                _transferBinOrderRepository.AddEntity(m);
                _unitOfWork.SaveChangesEntity();
                item.OrderId = m.Id;
                item.OrderSn = m.OrderSn;
                item.Status = 0;
                item.MaterialId = ilists.First().MaterialId;
                item.MaterialName = ilists.First().MaterialName;
                item.FromWhId = ilists.First().WarehouseId;
                item.FromWhCode = ilists.First().WarehouseCode;
                item.FromWhName = ilists.First().WarehouseName;
                item.FromRegionId = ilists.First().AreaId;
                item.FromRegionCode = ilists.First().AreaCode;
                item.FromRegionName = ilists.First().AreaName;
                item.FromLocationName = ilists.First().LocationName;
                item.FromLocationCode = ilists.First().LocationCode;
                var tcobj = clist.FirstOrDefault(x => x.Id == item.ToLocationId);
                if (tcobj == null || tcobj.IsLock == true)
                {
                    message = "目标仓位异常！";
                    return false;
                }
                item.ToWhId = tcobj.WhId;
                item.ToWhCode = tcobj.WhCode;
                item.ToWhName = tcobj.WhName;
                item.ToRegionId = tcobj.AreaId;
                item.ToRegionCode = tcobj.AreaCode;
                item.ToRegionName = tcobj.AreaName;
                item.ToLocationCode = tcobj.Code;
                item.ToLocationName = tcobj.Name;
                item.ExpectedStackingQty = 1;
                item.Quantity = (int?)ilists.First().AvailableQty;
                item.ToLogicalPartCode = ilists.First().PalletBarcode;
                _transferBinOrderDetailRepository.AddEntity(item);
                tcobj.IsLock = true;
                tcobj.FullStatus = 1;
                tcobj.BusinessType = 1;
                tcobj.ModifyDate = DateTime.Now;
                _cellRepository.UpdEntity(tcobj);
            }
            if (_unitOfWork.SaveChangesEntity())
            {
                _unitOfWork.CommitChanges();
                return true;
            }
            _unitOfWork.RollbackChanges();
            return true;
        }

        public bool DelTransferBinOrder(long id, out string message)
        {
            message = string.Empty;
            var tobj = _transferBinOrderRepository.QueryEntityById(id);
            if (tobj != null)
            {
                if (tobj.Status == 3 || tobj.Status == 4)
                {
                    message = "作业中和已完成的数据无法删除！";
                    return false;
                }
                _transferBinOrderRepository.DelEntity(tobj);
                var tdobj = _transferBinOrderDetailRepository.QueryEntityWhere(x => x.OrderId == tobj.Id);
                if (tdobj == null)
                {
                    message = "明细信息有误！";
                    return false;
                }
                _transferBinOrderDetailRepository.DelEntity(tdobj);
                if (tdobj.ToLocationId == null)
                {
                    message = "目标仓位信息有误！";
                    return false;
                }
                var cobj = _cellRepository.QueryEntityById((long)tdobj.ToLocationId);
                if (cobj != null && cobj.IsLock == false)
                {
                    message = "仓位状态有误！";
                    return false;
                }
                if (cobj != null)
                {
                    cobj.FullStatus = 0;
                    cobj.IsLock = false;
                    cobj.BusinessType = 0;
                    cobj.ModifyDate = DateTime.Now;
                    _cellRepository.UpdEntity(cobj);
                }
                var iobj = _inventoryRepository.QueryEntityWhere(x => x.LocationId == tdobj.FromLocationId);
                if (iobj != null)
                {
                    iobj.IsLock = false;
                    _inventoryRepository.UpdEntity(iobj);
                }
                return _unitOfWork.SaveChangesEntity();
            }
            message = "找不到移库单数据！";
            return false;
        }

        public TransferBinOrder? GetTransferBinOrderById(long id)
        {
            var tobj = _transferBinOrderRepository.QueryEntityById(id);
            if (tobj != null)
            {
                var tdobj = _transferBinOrderDetailRepository.QueryEntityWhere(x => x.OrderId == tobj.Id);
                if (tdobj != null)
                    tobj.OrderDetailList.Add(tdobj);
                return tobj;
            }
            return null;
        }

        public List<TransferBinOrder> GetTransferBinOrderList(string? key, int status, int pageIndex, int pageSize, out int totalCount)
        {
            var tlist = _transferBinOrderRepository.GetEntityAlls();
            if (!string.IsNullOrEmpty(key))
            {
                tlist = tlist.Where(c => c.OrderSn.Contains(key));
            }
            if (status < 8)
            {
                tlist = tlist.Where(c => c.Status == status);
            }
            var list = _transferBinOrderRepository.GetEntityAlls(tlist, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return list.ToList();
        }

        public bool UpdTransferBinOrder(TransferBinOrder m, out string message)
        {
            message = "";
            if (m.Status == 3 || m.Status == 4)
            {
                message = "作业中和已完成的单据不可修改！";
                return false;
            }
            var ilist = _inventoryRepository.GetEntityAlls();
            var clist = _cellRepository.GetEntityAlls();
            _unitOfWork.BeginTransaction();
            var tdobj = _transferBinOrderDetailRepository.QueryEntityWhere(x => x.OrderId == m.Id);
            if (tdobj != null)
                _transferBinOrderDetailRepository.DelEntity(tdobj);
            foreach (var item in m.OrderDetailList)
            {
                var iobj = ilist.FirstOrDefault(x => x.LocationId == item.FromLocationId && x.Status == 1);
                if (iobj == null)
                {
                    message = "找不到库存信息！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                _transferBinOrderRepository.UpdEntity(m);
                _unitOfWork.SaveChangesEntity();
                item.OrderId = m.Id;
                item.OrderSn = m.OrderSn;
                item.Status = 0;
                item.MaterialId = iobj.MaterialId;
                item.MaterialName = iobj.MaterialName;
                item.FromWhId = iobj.WarehouseId;
                item.FromWhCode = iobj.WarehouseCode;
                item.FromWhName = iobj.WarehouseName;
                item.FromRegionId = iobj.AreaId;
                item.FromRegionCode = iobj.AreaCode;
                item.FromRegionName = iobj.AreaName;
                item.FromLocationName = iobj.LocationName;
                item.FromLocationCode = iobj.LocationCode;
                var tcobj = clist.FirstOrDefault(x => x.Id == item.ToLocationId);
                if (tcobj == null || tcobj.IsLock == true)
                {
                    message = "目标仓位异常！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                item.ToWhId = tcobj.WhId;
                item.ToWhCode = tcobj.WhCode;
                item.ToWhName = tcobj.WhName;
                item.ToRegionId = tcobj.AreaId;
                item.ToRegionCode = tcobj.AreaCode;
                item.ToRegionName = tcobj.AreaName;
                item.ToLocationCode = tcobj.Code;
                item.ToLocationName = tcobj.Name;
                item.ExpectedStackingQty = 1;
                item.Quantity = (int?)iobj.AvailableQty;
                item.ToLogicalPartCode = iobj.PalletBarcode;
                _transferBinOrderDetailRepository.AddEntity(item);
            }
            if (_unitOfWork.SaveChangesEntity())
            {
                _unitOfWork.CommitChanges();
                return true;
            }
            _unitOfWork.RollbackChanges();
            return true;
        }
        #endregion

        #region PDA
        public bool StartTransferBinOrder(TransferBinOrderDTO m, out string message)
        {
            message = string.Empty;
            //bool result = false;
            List<Tasks> tasks = new List<Tasks>();
            _unitOfWork.BeginTransaction();
            try
            {
                var tranbdeobj = _transferBinOrderDetailRepository.QueryEntityById(m.Id);
                if (tranbdeobj == null)
                {
                    message = "找不到移库单明细！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (tranbdeobj.OrderId == null)
                {
                    message = "移库单id有误！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (tranbdeobj.Status == 3)
                {
                    message = "该任务正在作业中！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (tranbdeobj.Status == 4)
                {
                    message = "该任务已完成！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                var tranbobj = _transferBinOrderRepository.QueryEntityById((long)tranbdeobj.OrderId);
                if (tranbobj == null)
                {
                    message = "找不到移库单";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                tranbobj.Status = 3;
                tranbdeobj.Status = 3;
                
                #region 原始仓位和目标储位
                var fromCell = _cellRepository.QueryIsEntityWhere(it => it.Code == m.LocationCode);
                if (fromCell == null)
                {
                    message = "原始仓位不存在";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (fromCell.Status != 1 || fromCell.IsLock == false)
                {
                    message = "原始仓位，无法执行任务";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                var toCell = _cellRepository.QueryEntityWhere(c => c.Code == m.TargetLocationCode);
                if (toCell == null)
                {
                    message = "目标仓位不存在";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (toCell.Status != 1 || toCell.IsLock == false)
                {
                    message = "目标仓位，无法执行任务";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                #endregion
                int order = 1;
                //获取原始储位的其他仓位，其他仓位有货需要先移库它们
                var depthCell = fromCell.LineNo > 4 ? _cellRepository.GetEntityWhereAll(c => c.LayerNo == fromCell.LayerNo && c.ColumnNo == fromCell.ColumnNo && c.LineNo < fromCell.LineNo && c.LineNo > 4).OrderBy(c => c.DepthIndex).ToList() : _cellRepository.GetEntityWhereAll(c => c.LayerNo == fromCell.LayerNo && c.ColumnNo == fromCell.ColumnNo && c.LineNo > fromCell.LineNo && c.LineNo < 4).OrderBy(c => c.DepthIndex).ToList();
                foreach (var decell in depthCell)
                {
                    //查看仓位是否需要移库
                    var inventory = _inventoryRepository.QueryEntityWhere(i => i.LocationCode == decell.Code);
                    if (inventory is null)
                    {
                        continue; //如果仓位没有在库存中查询出数据代表仓位上没有物料可以直接下一个
                    }
                    if (inventory.Status == 4 || inventory.Status == 2)
                    {
                        continue; //如果库存数据等于移库和出库就代表已经下任务了不用再下任务了
                    }
                    if (inventory.Status == 3)
                    {
                        message = "移库仓位前有入库任务,等下在执行" + decell;
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (inventory.Status == 1) //如果是正常库存需要进行移库
                    {
                        //传入的是需要移库的仓位数据
                        var transCellData = TransferBinInventory(decell.LayerNo, decell.Code, decell.AreaCode, null,null,null, out message);
                        if (transCellData == null)
                        {
                            message = "创建移库任务失败，" + message;
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        //查询移库单
                        var putaway = _pingOrderRepository.QueryEntityWhere(p => p.Status == 4 && p.LocationCode == transCellData.Code && p.SourceType == 3);
                        if (putaway == null)
                        {
                            message = "未查询到移库任务!";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        //添加移库任务
                        tasks.Add(new Tasks()
                        {
                            TaskId = putaway.Code,
                            TaskType = 2,
                            BarCode = putaway.PalletBarcode,
                            EndNode = putaway.LocationCode,
                            StartNode = decell.Code,
                            Order = order
                        });
                        order++;
                    }
                }

                //创建本次移库的仓位任务
                var  ToTransCellData = TransferBinInventory(fromCell.LayerNo, fromCell.Code, fromCell.AreaCode, toCell, tranbobj.Id,m.Id,out message);
                if (ToTransCellData == null)
                {
                    message = "创建移库任务失败，" + message;
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                //查询本次移库仓位的移库单
                var putawayTo = _pingOrderRepository.QueryEntityWhere(p => p.Status == 4 && p.LocationCode == ToTransCellData.Code && p.SourceType == 3);
                if (putawayTo == null)
                {
                    message = "未查询到移库任务!";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                putawayTo.SiteCode = ToTransCellData.Code;
                if (!_unitOfWork.SaveChangesEntity())
                {
                    message = "移库站台修改失败!";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                //添加移库任务
                tasks.Add(new Tasks()
                {
                    TaskId = putawayTo.Code,
                    TaskType = 2,
                    BarCode = putawayTo.PalletBarcode,
                    EndNode = putawayTo.LocationCode,
                    StartNode = fromCell.Code,
                    Order = order
                });

                //查看当前环境
                if (Config.IsDev == false)
                {
                    //调用速锐wcs下发任务
                    TaskAccept taskAccept = new TaskAccept()
                    {
                        tasks = tasks,
                        GroupId = Guid.NewGuid().ToString("N"),
                        MsgTime = DateTime.Now.ToString(),
                        Warehouse = Config.WMSWarehouseCode
                    };
                    var newWcsApi = wcsHttp.TaskAcceptApi(taskAccept);
                    if (newWcsApi.returnStatus != 0)
                    {
                        message = newWcsApi.returnInfo;
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                }
                //提交事务
                _unitOfWork.CommitChanges();
                return true;
            }
            catch (Exception ex)
            {
                //事务回滚
                _unitOfWork.RollbackChanges();
                throw;
            }
        }


        private Cell? TransferBinInventory(int layerno, string trancellcode, string acode, Cell? toCell, long? tranbobj, long? mId,out string message)
        {
            message = string.Empty;
            #region 修改库存状态
            if (toCell == null)
            {
                toCell = GetCellCode(acode, layerno, out message);
                if (toCell == null)
                {
                    message = "当前层没有可移库的仓位了！";
                    return null;
                }
                toCell.FullStatus = 1;
                toCell.IsLock = true;
                toCell.BusinessType = 1;
                toCell.ModifyDate = DateTime.Now;
                _cellRepository.UpdEntity(toCell);
            }
           
            bool isshipplost = false;
            var tinventorylist = _inventoryRepository.GetEntityWhereAll(it => it.LocationCode == trancellcode).ToList();
            if (!tinventorylist.Any())
            {
                message = "库存不存在";
                return null;
            }
            foreach (var inventory in tinventorylist)
            {
                inventory.LocationId = toCell.Id;
                inventory.LocationName = toCell.Name;
                inventory.LocationCode = toCell.Code;
                inventory.LocationDepth = toCell.DepthIndex;
                inventory.LocationLineNo = toCell.LineNo;
                inventory.LocationLayerNo = toCell.LayerNo;
                inventory.LocationColumnNo = toCell.ColumnNo;
                inventory.Status = 2;
                inventory.LocationHeightType = toCell.HeightType;
                inventory.IsLock = true;
                inventory.RoutewayId = toCell.RoutewayId;
                inventory.ErplocationCode = toCell.Erpcode;
                if (isshipplost)
                    inventory.Remark = "系统移库";
                _inventoryRepository.UpdEntity(inventory);
                #region 关联的入库单做处理
                if (inventory.RelatedOrderDetailId == null)
                {
                    message = "关联的入库单id有误！";
                    return null;
                }
                var revingobj = _receivingOrderDetailRepository.QueryEntityById((long)inventory.RelatedOrderDetailId);
                if (revingobj == null)
                {
                    message = "入库单明细不存在或已被删除";
                    return null;
                }
                else
                {
                    revingobj.LocationId = toCell.Id;
                    revingobj.LocationCode = toCell.Code;
                    revingobj.LocationName = toCell.Name;
                    revingobj.ModifyDate = DateTime.Now;
                    _receivingOrderDetailRepository.UpdEntity(revingobj);
                }
                #region 指令管理
                Instruct instruct = null;
                instruct = new Instruct
                {
                    Id = YitIdHelper.NextId(),
                    WarehouseCode = toCell.WhCode,
                    Status = 2,
                    FromLocation = trancellcode,
                    ToLocation = toCell.Code,
                    StackingStorageId = 0,
                    WorkDeviceType = 1,
                    InstructType = 3,
                    Action = 0,
                    RelatedOrderId = tranbobj,
                    RelatedOrderDetailId = mId,
                    DeviceCode = "",
                    ExpectedToLocation = toCell.Code,
                    InstructIndex = 1,
                    PalletBarcode = inventory.PalletBarcode,
                    ScanedBarcode = inventory.PalletBarcode,
                    Priority = 9999,
                    Qty = inventory.AvailableQty == null ? 0 : (decimal)inventory.AvailableQty,
                    FinishedQty = 0,
                    CreateDate = DateTime.Now,
                    BusinessType = (int)EmBusinessType.Move,
                    BillType = (int)revingobj.BillType.GetValueOrDefault(),
                };
                _instructRepository.AddEntity(instruct);
                #endregion
                #endregion


                #endregion
                #region 上架单
                string tstr = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                string traawayCode = "TRA" + tstr;
                PutawayOrder putawayOrder = new PutawayOrder();
                putawayOrder.Id = YitIdHelper.NextId();
                putawayOrder.Code = traawayCode;
                putawayOrder.RelatedOrderDetailId = tinventorylist.First().RelatedOrderDetailId;
                putawayOrder.StackingStorageId = 0;
                putawayOrder.PalletBarcode = tinventorylist.First().PalletBarcode;
                putawayOrder.LocationCode = toCell.Code;
                putawayOrder.LocationDepth = toCell.DepthIndex == 0 ? null : toCell.DepthIndex;
                putawayOrder.Status = 4;
                putawayOrder.Qty = tinventorylist.First().AvailableQty;
                putawayOrder.CreateDate = DateTime.Now;
                putawayOrder.MaterialId = tinventorylist.First().MaterialId;
                putawayOrder.MaterialCode = tinventorylist.First().MaterialCode;
                putawayOrder.MaterialName = tinventorylist.First().MaterialName;
                putawayOrder.MaterialKeyId = tinventorylist.First().MaterialKeyId;
                putawayOrder.BatchNo = tinventorylist.First().BatchNo;
                putawayOrder.CreateUserId = 0;
                putawayOrder.CreateUserName = "系统";
                putawayOrder.SourceType = 3;
                putawayOrder.SiteCode = "";
                _pingOrderRepository.AddEntity(putawayOrder);
            }
            var pallobj = _alletRepository.QueryEntityWhere(x => x.LocationCode == trancellcode);
            if (pallobj != null)
            {
                pallobj.LocationName = toCell.Name;
                pallobj.LocationCode = toCell.Code;
            }

            #endregion
            if (!_unitOfWork.SaveChangesEntity())
            {
                message = "修改数据失败";
                return null;
            }

            return toCell;
        }

        private Cell? GetCellCode(string acode, int layerno, out string message)
        {
            message = string.Empty;
            if (string.IsNullOrEmpty(acode))
            {
                message = "库区编码有误！";
                return null;
            }
            Cell? cellobj = new Cell();
            //获取所有库区
            var areaobj = areaRepository.QueryIsEntityWhere(x => x.Code == acode && x.Status == 1);
            if (areaobj == null || areaobj.WhId == null)
            {
                message = "库区不存在或已被禁用!";
                return null;
            }
            long? wid = areaobj.WhId;
            //获取所有库房
            var warehouseobj = warehouseRepository.QueryIsEntityWhere(x => x.Id == wid && x.Status == 1);
            if (warehouseobj == null)
            {
                message = "库房不存在或已被禁用!";
                return null;
            }

            //获取所有巷道
            var routewayQuery = routewayRepository.GetEntityWhereAll(x => x.WhId == wid && x.Status == 1);
            if (routewayQuery == null)
            {
                message = "无可用巷道!";
                return null;
            }
            List<long> enabledRoutewayIds = routewayQuery.Select(t => t.Id).ToList();//只取巷道id
            // 获取所有货架
            var shelves = shelfRepository.GetEntityWhereAll(x => x.WhId == wid && x.AreaId == areaobj.Id && x.Status == 1 && enabledRoutewayIds.Contains((long)x.RoutewayId));
            if (shelves == null)
            {
                message = "无可用货架!";
                return null;
            }
            List<long> enabledShelves = shelves.Select(t => t.Id).ToList();//只取货架id
            //获取所有可用仓位
            var cellQuery = _cellRepository
                .GetEntityWhereAll(x => x.AreaCode == acode
                                        && x.Status == 1
                                        && x.FullStatus == 0
                                        && x.IsLock == false
                                        && x.LayerNo == layerno
                                        && enabledRoutewayIds.Contains((long)x.RoutewayId)
                                        && enabledShelves.Contains((long)x.ShelfId)).ToList();
            if (!cellQuery.Any())
            {
                message = "无可用仓位!";
                return null;
            }
            //var inventoryQuery = Context.TInventory.AsNoTracking(); //获取库存数据
            cellobj = cellQuery.Where(x => x.IsMaxDepth == true).OrderByDescending(c => c.DepthIndex)
                                .ThenBy(c => c.LayerNo)
                                .ThenBy(c => c.ColumnNo)
                                .ThenBy(c => c.LineNo)
                                .FirstOrDefault();
            if (cellobj != null)
            {
                return cellobj;
            }
            else
            {
                cellobj = cellQuery.Where(x => x.IsMaxDepth == false).OrderByDescending(c => c.DepthIndex)
                              .ThenBy(c => c.LayerNo)
                              .ThenBy(c => c.ColumnNo)
                              .ThenBy(c => c.LineNo)
                              .FirstOrDefault();
                if (cellobj != null)
                {
                    return cellobj;
                }
            }
            if (cellobj == null)
                message = "无可用仓位!";
            return null;
        }

        private bool StaticFinishTransferBinOrder(string putcode, out string message)
        {
            message = string.Empty;
            var putobj = _pingOrderRepository.QueryEntityWhere(x => x.Code == putcode && x.SourceType == 3 && x.Status == 4);
            var robj = _receivingOrderDetailRepository.GetEntityAlls();
            if (putobj == null)
            {
                message = "找不到上架单！";
                return false;
            }
            string? pallbarcode = putobj.PalletBarcode;
            if (string.IsNullOrEmpty(pallbarcode))
            {
                message = "托盘信息有误！";
                return false;
            }
            var instructlist = _instructRepository.GetEntityWhereAll(x => x.PalletBarcode == pallbarcode && x.Status == 2 && x.InstructType == 3).ToList();
            if (!instructlist.Any())
            {
                message = "未查询到指令！";
                return false;
            }
            var tlist = _transferBinOrderRepository.GetEntityAll();
            var tdlist = _transferBinOrderDetailRepository.GetEntityAll();
            foreach (var instruct in instructlist)
            {
                instruct.Status = 4;
                instruct.EndTime = DateTime.Now;
                _instructRepository.UpdEntity(instruct);
                var fromcell = _cellRepository.QueryEntityWhere(x => x.Code == instruct.FromLocation && x.FullStatus == 1);
                if (fromcell != null)
                {
                    fromcell.FullStatus = 0;
                    fromcell.IsLock = false;
                    fromcell.BusinessType = 0;
                    _cellRepository.UpdEntity(fromcell);
                    
                }
                var invobj = _inventoryRepository.QueryEntityWhere(x => x.PalletBarcode == instruct.PalletBarcode && x.Status == 2 && x.IsLock == true);
                if (invobj == null)
                {
                    message = "库存中找不到该托盘！";
                    return false;
                }
                if(invobj.Remark!="系统移库")
                {
                    invobj.Status = 1;
                    invobj.IsLock = false;
                }
                else
                    invobj.Status = 1;
                invobj.Remark = string.Empty;
                _inventoryRepository.UpdEntity(invobj);
                var tobj = tlist.FirstOrDefault(x => x.Id == instruct.RelatedOrderId);
                if (tobj != null)
                {
                    tobj.Status = 4;
                    _transferBinOrderRepository.UpdEntity(tobj);
                }
                var tdobj = tdlist.FirstOrDefault(x => x.OrderId == instruct.RelatedOrderId);
                if (tdobj != null)
                {
                    tdobj.Status = 4;
                    _transferBinOrderDetailRepository.UpdEntity(tdobj);
                }

                var slocklist2 = _lockCellRepository.GetEntityWhereAll(x => x.CellCode == instruct.ToLocation && x.Status != 4).ToList();
                foreach (var item3 in slocklist2)
                {
                    item3.Status = 0;
                    _lockCellRepository.UpdEntity(item3);
                }
                var treivingobj = robj.FirstOrDefault(x => x.Id == invobj.RelatedOrderDetailId);
                if (treivingobj == null)
                {
                    message = "找不到入库单或已被删除！";
                    return false;
                }
                var inventoryLog = new InventoryLog
                {
                    Id = YitIdHelper.NextId(),
                    SourceType = 4,
                    SourceSn = treivingobj.OrderSn,
                    WarehouseId = invobj.WarehouseId,
                    WarehouseName = invobj.WarehouseName,
                    AreaName = invobj.AreaName,
                    AreaId = invobj.AreaId,
                    LocationCode = invobj.LocationCode,
                    PalletBarcode = instruct.PalletBarcode,
                    MaterialId = invobj.MaterialId,
                    MaterialCode = invobj.MaterialCode,
                    MaterialName = invobj.MaterialName,
                    BatchNo = invobj.BatchNo,
                    StartQty = invobj.AvailableQty,
                    ChangeQty = 0,
                    EndQty = invobj.AvailableQty,
                    BaseUnitId = 0,
                    BaseUnitName = invobj.UnitName,
                    Remark = "原：" + instruct.FromLocation,
                    CreateDate = DateTime.Now
                };
                _inventoryLogRepository.AddEntity(inventoryLog);
            }
            var putlist = _pingOrderRepository.GetEntityWhereAll(x => x.SourceType == 3 && x.Status == 4 && x.PalletBarcode == pallbarcode);
            foreach (var item in putlist)
            {
                item.Status = 5;
                item.Fifodate = DateTime.Now;
                _pingOrderRepository.UpdEntity(item);
            }

            return _unitOfWork.SaveChangesEntity();
        }

        public bool FinishTransferBinOrder(string putcode, out string message)
        {
            _unitOfWork.BeginTransaction();
            try
            {
                bool result = StaticFinishTransferBinOrder(putcode, out message);
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }
        #endregion
    }
}
